package com.lrkj.payfee.service.impl;

import com.lrkj.common.annotation.DataScope;
import com.lrkj.common.core.domain.AjaxResult;
import com.lrkj.common.exception.BaseException;
import com.lrkj.common.utils.DateUtils;
import com.lrkj.common.utils.uuid.IdUtils;
import com.lrkj.conf.PreferentialMethodConf;
import com.lrkj.payfee.domain.FavouredConf;
import com.lrkj.payfee.domain.FavouredNorm;
import com.lrkj.payfee.domain.FavouredPolicy;
import com.lrkj.payfee.domain.RuleCost;
import com.lrkj.payfee.mapper.FavouredConfMapper;
import com.lrkj.payfee.mapper.FavouredPolicyMapper;
import com.lrkj.payfee.mapper.RuleCostMapper;
import com.lrkj.payfee.service.IFavouredConfService;
import com.lrkj.payfee.service.IFavouredNormService;
import com.lrkj.payfee.service.IFavouredPolicyService;
import com.lrkj.payfee.vo.ConsequenceInVo;
import com.lrkj.property.domain.Community;
import com.lrkj.property.service.ICommunityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 优惠政策Service业务层处理
 *
 * @author yajun_ren
 * @date 2021-08-14
 */
@Service
public class FavouredPolicyServiceImpl implements IFavouredPolicyService {
    @Autowired
    private FavouredPolicyMapper favouredPolicyMapper;

    @Autowired
    private FavouredConfMapper favouredConfMapper;

    @Autowired
    private IFavouredNormService favouredNormService;

    @Autowired
    private IFavouredConfService favouredConfService;

    @Autowired
    private ICommunityService communityService;

    @Autowired
    private RuleCostMapper ruleCostMapper;


    /**
     * 查询优惠政策
     *
     * @param favouredPolicyId 优惠政策ID
     * @return 优惠政策
     */
    @Override
    public FavouredPolicy selectFavouredPolicyById(String favouredPolicyId) {
        return favouredPolicyMapper.selectFavouredPolicyById(favouredPolicyId);
    }

    /**
     * 查询优惠政策列表
     *
     * @param favouredPolicy 优惠政策
     * @return 优惠政策
     */
    @Override
    @DataScope(deptAlias = "t")
    public List<FavouredPolicy> selectFavouredPolicyList(FavouredPolicy favouredPolicy) {
        return favouredPolicyMapper.selectFavouredPolicyList(favouredPolicy);
    }

    /**
     * 新增优惠政策
     *
     * @param favouredPolicy 优惠政策
     * @return 结果
     */
    @Override
    @Transactional
    public int insertFavouredPolicy(FavouredPolicy favouredPolicy) {
        favouredPolicy.setFavouredPolicyId(IdUtils.simpleUUID());
        favouredPolicy.setCreateTime(DateUtils.getNowDate());
        this.savaOrUpdateConf(favouredPolicy);
        this.savaOrUpdateNorm(favouredPolicy);
        this.setUnitInfo(favouredPolicy);
        return favouredPolicyMapper.insertFavouredPolicy(favouredPolicy);
    }

    /**
     * 修改优惠政策
     *
     * @param favouredPolicy 优惠政策
     * @return 结果
     */
    @Override
    public int updateFavouredPolicy(FavouredPolicy favouredPolicy) {
        favouredPolicy.setUpdateTime(DateUtils.getNowDate());
        this.savaOrUpdateConf(favouredPolicy);
        this.savaOrUpdateNorm(favouredPolicy);
        this.setUnitInfo(favouredPolicy);
        return favouredPolicyMapper.updateFavouredPolicy(favouredPolicy);
    }

    private void setUnitInfo(FavouredPolicy bean) {
        Community parentBean = communityService.selectCommunityById(bean.getCommunityId());
        bean.setDeptId(parentBean.getDeptId());
        bean.setAncestors(parentBean.getAncestors() + "," + bean.getCommunityId());
    }

    //新增或修改政策设置
    private void savaOrUpdateConf(FavouredPolicy favouredPolicy) {
        List<FavouredConf> favouredConfs = favouredPolicy.getFavouredConfs();
        //删除优惠政策设置
        favouredConfService.deleteFavouredPolicyId(favouredPolicy.getFavouredPolicyId());
        if (null != favouredConfs && favouredConfs.size() > 0) {
            favouredConfs.stream().forEach(x -> {
                x.setFavouredConfId(IdUtils.simpleUUID());
                x.setFavouredPolicyId(favouredPolicy.getFavouredPolicyId());
            });
            favouredConfService.doSaveList(favouredConfs);
        }
    }

    //新增或修改政策设置
    private void savaOrUpdateNorm(FavouredPolicy favouredPolicy) {
        List<FavouredNorm> favouredNorms = favouredPolicy.getFavouredNorms();
        //删除优惠关联的收费标准
        favouredNormService.deleteFavouredNormById(favouredPolicy.getFavouredPolicyId());
        if (null != favouredNorms && favouredNorms.size() > 0) {
            favouredNorms.stream().forEach(x -> {
                x.setFavouredPolicyId(favouredPolicy.getFavouredPolicyId());
            });
            favouredNormService.doSaveList(favouredNorms);
        }
    }

    /**
     * 批量删除优惠政策
     *
     * @param favouredPolicyIds 需要删除的优惠政策ID
     * @return 结果
     */
    @Override
    public int deleteFavouredPolicyByIds(String[] favouredPolicyIds) {
        return favouredPolicyMapper.deleteFavouredPolicyByIds(favouredPolicyIds);
    }

    /**
     * 删除优惠政策信息
     *
     * @param favouredPolicyId 优惠政策ID
     * @return 结果
     */
    @Override
    public int deleteFavouredPolicyById(String favouredPolicyId) {
        return favouredPolicyMapper.deleteFavouredPolicyById(favouredPolicyId);
    }

    @Override
    public int updateStatus(FavouredPolicy favouredPolicy) {
        FavouredPolicy oldBean = favouredPolicyMapper.selectFavouredPolicyById(favouredPolicy.getFavouredPolicyId());
        if (null != oldBean) {
            oldBean.setStatus(favouredPolicy.getStatus());
            return favouredPolicyMapper.updateFavouredPolicy(oldBean);
        } else {
            throw new BaseException("数据异常");
        }
    }

    @Override
    public AjaxResult consequenceBack(ConsequenceInVo consequenceInVo) {
        BigDecimal money=consequenceInVo.getMoney();
        //获取当前政策
        FavouredPolicy favouredPolicy = favouredPolicyMapper.selectFavouredPolicyById(consequenceInVo.getFavouredPolicyId());
        if (favouredPolicy == null) {
            return AjaxResult.error("策略未找到！");
        }

        //检测配置
        FavouredConf favouredConf = favouredConfMapper.selectFavouredConfByPolicyId(favouredPolicy.getFavouredPolicyId());
        if (favouredConf == null) {
            return AjaxResult.error("策略配置详情未找到！");
        }

        //判断是否在策略时间区间
        if (!DateUtils.isSection(favouredPolicy.getBeginTime(), favouredPolicy.getFinishTime())) {
            return AjaxResult.error("策略已经过期！");
        }
        //判断小区
        if (!favouredPolicy.getCommunityId().equals(consequenceInVo.getCommunityId())) {
            return AjaxResult.error("该小区无法试用此策略！");
        }
        //判断政策类型
        switch (consequenceInVo.getPreferentialMethod()) {
            case PreferentialMethodConf.Conf.JM: //减免
                switch (consequenceInVo.getPreferentialType()) {
                    case PreferentialMethodConf.Conf.MJ: //满减
                        //计算满减条件
                        Temporal beginTime = LocalDate.parse(consequenceInVo.getBeginTime());
                        Temporal finishTime = LocalDate.parse(consequenceInVo.getFinishTime());
                        long l = ChronoUnit.MONTHS.between(beginTime, finishTime);
                        if (l < Long.getLong(favouredConf.getMature())) {
                            return AjaxResult.error("未达到满缴" + favouredConf.getMature() + "条件！");
                        }
                        break;

                    case PreferentialMethodConf.Conf.Qjj: //区间减
                        //判断是否在区间
                        Date beginMonth = DateUtils.parseDate(favouredConf.getBeginMonth());
                        Date finishMonth = DateUtils.parseDate(favouredConf.getFinishMonth());
                        if (!DateUtils.isSection(beginMonth, finishMonth)) {
                            return AjaxResult.error("不在减免区间！");
                        }
                        break;
                }
                break;
        }
        //核对收费标准
        if(!checkChargeNorm(favouredConf,consequenceInVo)){
            return AjaxResult.error("收费标准不对！");
        }

        //核对使用标准
        if(!checkChargeNormApply(favouredConf,consequenceInVo)){
            return AjaxResult.error("应用标准不对");
        }

        //政策设置-》减免方式 reliefMethod
        if(consequenceInVo.getReliefMethod().equals(PreferentialMethodConf.Conf.JMGDJE)){
            //减免固定金额
            money=calculateSum(money,favouredConf.getMoney());
            BigDecimal jmMoney=BigDecimal.ZERO;

            //分摊方式
            switch (favouredPolicy.getSharingMethod()) {

                case PreferentialMethodConf.Conf.AYJT: //按月均摊
                    //DateUtils.get
                    jmMoney=money.divide(new BigDecimal(12),2);
                    break;

                case PreferentialMethodConf.Conf.CQWH: //从前往后
                    break;

                case PreferentialMethodConf.Conf.CHWQ: //从后往前
                    break;
            }

            saveRuleCost(consequenceInVo.getRoomId(),jmMoney);


        }else if(consequenceInVo.getReliefMethod().equals(PreferentialMethodConf.Conf.JMYDFY)){
            BigDecimal jmMoney=BigDecimal.ZERO;
            //减免月份
             String month=favouredConf.getDerateMonth();
            //分摊方式
            switch (favouredPolicy.getSharingMethod()) {

                case PreferentialMethodConf.Conf.AYJT: //按月均摊
                    jmMoney=money.divide(new BigDecimal(month),2);
                    break;

                case PreferentialMethodConf.Conf.CQWH: //从前往后
                    break;

                case PreferentialMethodConf.Conf.CHWQ: //从后往前
                    break;
            }
            saveRuleCost(consequenceInVo.getRoomId(),jmMoney);
            //总金额
            money=calculateSum(money,favouredConf.getMoney());
        }


        return AjaxResult.success(money);
    }

    public void saveRuleCost(String roomId,BigDecimal jmMoney){
        RuleCost ruleCost =new RuleCost();
        ruleCost.setRoomId(roomId);
        List<RuleCost> list=ruleCostMapper.selectRuleCostList(ruleCost);
        if(list.size() > 0){
            List<RuleCost> updateList=list.stream().peek(a->{
                a.setSpecialMoney(jmMoney);
                a.setMoneys(calculateSum(a.getMoneys(),jmMoney));
                a.setUpdateTime(DateUtils.getNowDate());
            }).collect(Collectors.toList());
            ruleCostMapper.updateBatch(updateList);
        }
    }

    /**
     * 计算金额
     * @return
     */
    public BigDecimal calculateSum(BigDecimal money,BigDecimal minusMoney){
        money=money.subtract(minusMoney);
        return  money.compareTo(BigDecimal.ZERO)==-1?BigDecimal.ZERO:money;
    }

    /**
     * @author huxy
     * @创建时间 2022/8/11 10:11 AM
     * @param favouredConf
     * @备注  核对应用 费用标准
     * @节点
    */
    public boolean checkChargeNormApply(FavouredConf favouredConf,ConsequenceInVo consequenceInVo){
        return favouredConf.getNormApply().equals(consequenceInVo.getNormId());
    }
    /**
     * @author huxy
     * @创建时间 2022/8/11 9:53 AM
     * @param favouredConf
     * @备注 核对收费标准
     * @节点
    */
    public boolean checkChargeNorm(FavouredConf favouredConf,ConsequenceInVo consequenceInVo){
       return favouredConf.getNormCn().equals(consequenceInVo.getNormId());
    }

}
